﻿using DataType.Actions;
using DataType.JudgeResults;
using OprsSimulator.Operators;
using System.Collections.Generic;
using MapCalclator;
using DataType.CustomEnumType;
using System;
using static System.Collections.Specialized.BitVector32;
using OprsSimulator.OprAttributes;
using DataType;
using DataType.MessageType;
using System.Diagnostics;

namespace ActionsJudge
{
    internal static class MoveJudge
    {
        public static List<IJudgeResult> ToJudge(IBasicAction act, List<IOperator> oprs, Map map)
        {
            List<IJudgeResult> judgeResults = new List<IJudgeResult>();// 保存裁决结果，用于返回

            MoveAction action = (MoveAction)act;// 转换为机动动作MoveAction类型
            IOperator opr = null;// 寻找算子
            foreach (IOperator oper in oprs)
            {
                if (oper.ObjID == action.ObjID)
                {
                    opr = oper;
                    break;
                }
            }
            //判断opr
            if (opr == null)
            {
                Trace.TraceWarning($"无效裁决：态势中没有ID为{action.ObjID}的算子");
                return new List<IJudgeResult>();
            }
            if (!typeof(ICommonAttris).IsAssignableFrom(opr.GetType()))
            {
                Trace.TraceWarning($"无效裁决：算子{action.ObjID}没有基础属性");
                return new List<IJudgeResult>();
            }
            if (!typeof(IMoveAttris).IsAssignableFrom(opr.GetType()))
            {
                Trace.TraceWarning($"无效裁决：算子{action.ObjID}不可机动");     //判断算子是否继承了IMoveAttris
                return new List<IJudgeResult>();
            }
            //获取算子的属性
            int speed = (int)opr.GetType().GetProperty("Speed").GetValue(opr);
            bool can_to_move = (bool)opr.GetType().GetProperty("CanToMove").GetValue(opr);
            int move_to_stop_remain_time = (int)opr.GetType().GetProperty("MoveToStopRemainTime").GetValue(opr);
            MoveStateType move_state = (MoveStateType)opr.GetType().GetProperty("MoveState").GetValue(opr);
            int cur_hex = (int)opr.GetType().GetProperty("CurHex").GetValue(opr);
            int get_on_remain_time = (int)opr.GetType().GetProperty("GetOnRemainTime").GetValue(opr);
            int get_off_remain_time = (int)opr.GetType().GetProperty("GetOffRemainTime").GetValue(opr);
            int change_state_remain_time = (int)opr.GetType().GetProperty("ChangeStateRemainTime").GetValue(opr);
            OprType oprType = (OprType)opr.GetType().GetProperty("Type").GetValue(opr);
            int oprTire = (int)opr.GetType().GetProperty("Tire").GetValue(opr);
            bool keep = (bool)opr.GetType().GetProperty("Keep").GetValue(opr);
            OprSubType sub_type = (OprSubType)opr.GetType().GetProperty("Subtype").GetValue(opr);
            int weapon_unfold_time = (int)opr.GetType().GetProperty("WeaponUnfoldTime").GetValue(opr);

            bool flag_move = true;// 可以机动的标志位
            if (speed > 0)
            {
                Trace.TraceWarning($"MoveJudge无效裁决：未停下来的算子{action.ObjID}不可下达机动命令");
                flag_move = false;
            }
            else
            {
                if (!can_to_move && move_to_stop_remain_time > 0)  // 正处于强制停止的判断
                {
                    Trace.TraceWarning($"无效裁决：强制停止中的算子不可下达机动命令");
                    flag_move = false;
                }
            }
            if (action.Type != ActionType.Move)
            {
                Trace.TraceWarning("无效裁决：算子的动作类型有误，应该是机动类型");
                flag_move = false;
            }
            if (action.MovePath.Count <= 0)
            {
                Trace.TraceWarning($"无效裁决：算子的动作路径为空");
                flag_move = false;
            }
            if (get_on_remain_time > 0 || get_off_remain_time > 0 || change_state_remain_time > 0)
            {
                Trace.TraceWarning($"无效裁决：算子正在上下车或者切换状态,不能机动");
                flag_move = false;
            }
            if (weapon_unfold_time > 0)
            {
                Trace.TraceWarning($"无效裁决：算子正在展开或者锁定武器,不能机动");
                flag_move = false;
            }
            if (sub_type == OprSubType.Infantry && keep)
            {
                Trace.TraceWarning($"无效裁决：人员算子被压制,不能机动");
                flag_move = false;
            }

            // 1.行军状态的可机动的判断
            if (move_state == MoveStateType.March)
            {
                // 判断能否机动到move_path的第一个六角格
                if (!map.GetHexCosts(cur_hex / 100, cur_hex % 100, MoveMode.VehicleMarch).ContainsKey(action.MovePath[0]))        //      以地对地为前提     所以用cost
                {
                    Trace.TraceWarning($"无效裁决：算子行军路线不通");
                    flag_move = false;
                }
                else
                {
                    // 判断move_path中每个六角格之间是不是通的
                    for (int i = 0; i < action.MovePath.Count - 1; i++)
                    {
                        int curHex = action.MovePath[i];// 本格
                        int next_hex = action.MovePath[i + 1];// 下一格
                        int cur_row = curHex / 100;// 行
                        int cur_col = curHex % 100;// 列
                        if (!map.GetHexCosts(cur_row, cur_col, MoveMode.VehicleMarch).ContainsKey(next_hex))
                        {
                            Trace.TraceWarning($"无效裁决：算子行军路线不通");
                            flag_move = false;
                            break;
                        }
                    }
                }
            }
            // 2.非行军状态的可机动的判断
            else if (move_state == MoveStateType.Normal || move_state == MoveStateType.Shelt || move_state == MoveStateType.HalfSpeed)// 正常机动，掩蔽，半速
            {
                MoveMode moveMode;// 记录机动类型
                if (oprType == OprType.Vehicle) moveMode = MoveMode.VehicleMove;// 车辆机动
                else if (oprType == OprType.Infantry) moveMode = MoveMode.Walk;// 步兵机动
                else moveMode = MoveMode.Fly;// 空中机动

                // 判断能否机动到move_path的第一个六角格
                if (!map.GetHexCosts(cur_hex / 100, cur_hex % 100, moveMode).ContainsKey(action.MovePath[0]))
                {
                    Trace.TraceWarning($"无效裁决：算子机动路线不通");
                    flag_move = false;
                }
                else
                {
                    // 判断move_path中每个六角格之间是不是通的
                    for (int i = 0; i < action.MovePath.Count - 1; i++)
                    {
                        int curHex = action.MovePath[i];// 本格
                        int next_hex = action.MovePath[i + 1];// 下一格
                        int cur_row = curHex / 100;// 行
                        int cur_col = curHex % 100;// 列
                        if (!map.GetHexCosts(cur_row, cur_col, moveMode).ContainsKey(next_hex))
                        {
                            Trace.TraceWarning($"无效裁决：算子机动路线不通");
                            flag_move = false;
                            break;
                        }
                    }
                }
            }
            // 3.一级冲锋状态的可机动的判断
            else if (move_state == MoveStateType.RushLevel1)
            {
                if (oprTire > 1)// 疲劳值大于1
                {
                    Trace.TraceWarning($"无效裁决：二级疲劳状态下不可进行一级冲锋");
                    flag_move = false;
                }
                // 判断能否机动到move_path的第一个六角格
                if (!map.GetHexCosts(cur_hex / 100, cur_hex % 100, MoveMode.Walk).ContainsKey(action.MovePath[0]))
                {
                    Trace.TraceWarning($"无效裁决：算子冲锋路线不通");
                    flag_move = false;
                }
                else
                {
                    // 判断move_path中每个六角格之间是不是通的
                    for (int i = 0; i < action.MovePath.Count - 1; i++)
                    {
                        int curHex = action.MovePath[i];// 本格
                        int next_hex = action.MovePath[i + 1];// 下一格
                        int cur_row = curHex / 100;// 行
                        int cur_col = curHex % 100;// 列
                        if (!map.GetHexCosts(cur_row, cur_col, MoveMode.Walk).ContainsKey(next_hex))
                        {
                            Trace.TraceWarning($"无效裁决：算子冲锋路线不通");
                            flag_move = false;
                            break;
                        }
                    }
                }              
            }
            // 4.二级冲锋状态的可机动的判断
            else if (move_state == MoveStateType.RushLevel2)
            {
                if (oprTire > 0)
                {
                    Trace.TraceWarning($"无效裁决：一级疲劳状态下不可进行二级冲锋");
                    flag_move = false;
                }
                // 判断能否机动到move_path的第一个六角格
                if (!map.GetHexCosts(cur_hex / 100, cur_hex % 100, MoveMode.Walk).ContainsKey(action.MovePath[0]))
                {
                    Trace.TraceWarning($"无效裁决：算子冲锋路线不通");
                    flag_move = false;
                }
                else
                {
                    // 判断move_path中每个六角格之间是不是通的
                    for (int i = 0; i < action.MovePath.Count - 1; i++)
                    {
                        int curHex = action.MovePath[i];// 本格
                        int next_hex = action.MovePath[i + 1];// 下一格
                        int cur_row = curHex / 100;// 行
                        int cur_col = curHex % 100;// 列
                        if (!map.GetHexCosts(cur_row, cur_col, MoveMode.Walk).ContainsKey(next_hex))
                        {
                            Trace.TraceWarning($"无效裁决：算子冲锋路线不通");
                            flag_move = false;
                            break;
                        }
                    }
                }
            }

            // 生成裁决结果，添加进judgeResults
            MoveJudgeResult moveJudgeResult = new MoveJudgeResult(action.ObjID, flag_move, action.MovePath);
            judgeResults.Add(moveJudgeResult);

            return judgeResults;
        }
    }
}
